package com.disney.domain.sdk.factory;

import com.google.common.collect.Lists;

import java.util.Comparator;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @author issavior
 */
public class DomainExecutor<E extends IDomainBiz> {


    private final Class<E> clazz;

    public DomainExecutor(Class<E> clazz) {
        this.clazz = clazz;
    }

    /**
     * 执行排序结果为第一个的扩展点
     *
     * @param target   请求体
     * @param callBack 函数定义
     * @param <T>
     * @param <R>
     * @return
     */
    public <T extends DomainRequest, R> R execFirst(T target, Function<E, R> callBack) {
        return Optional.ofNullable(DomainFactory.getBeans(target, clazz))
                .orElse(Lists.newArrayList())
                .stream()
                .filter(IDomainBiz::enable)
                .max(Comparator.comparingInt(IDomainBiz::byOrder))
                .map(callBack)
                .orElse(null);
    }

    /**
     * 执行所有扩展点
     *
     * @param target   请求体
     * @param consumer 函数定义
     * @param <T>
     */
    public <T extends DomainRequest> void execAll(T target, Consumer<E> consumer) {
        Optional.ofNullable(DomainFactory.getBeans(target, clazz))
                .orElse(Lists.newArrayList())
                .stream()
                .filter(IDomainBiz::enable)
                .forEach(consumer);
    }

    /**
     * 执行所有符合条件的扩展点
     *
     * @param target    请求体
     * @param consumer  函数定义
     * @param predicate 扩展点过滤方式
     * @param <T>
     */
    public <T extends DomainRequest> void execFilter(T target, Consumer<E> consumer, Predicate<E> predicate) {
        Optional.ofNullable(DomainFactory.getBeans(target, clazz))
                .orElse(Lists.newArrayList())
                .stream()
                .filter(IDomainBiz::enable)
                .filter(predicate)
                .forEach(consumer);
    }
}
